#include "mainwindow.h"
#include "ui_mainwindow.h"
#include "QFileDialog"
#include "SaveManager.h"
#include "errormanager.h"
#include <windows.h>
#include <stdio.h>
#include <stdlib.h>
#include <psapi.h>
#include <time.h>
#include "psapi.h"
#include <iostream>
#include <cstdlib>
#include "windows.h"
#include "QTimer"
#include "audiooutputer.h"
#include "settings.h"


HHOOK hHook;    // Handle from global hook
HINSTANCE hExe; // Handle from our exe
bool mystate = 0;
bool hasPrefix = 0;
int sem1=0;
int sem2=0;
int sem3=0;
int sem4=0;
int sem5=0;
Settings *settingWindow;

MainWindow::MainWindow(QWidget *parent) :
    QMainWindow(parent),
    ui(new Ui::MainWindow){
    ui->setupUi(this);

    QStringList commands;
    settingWindow = new Settings(this);

    // Gets current exe HANDLE
    hExe = GetModuleHandle(NULL);
    commands << "" << "CTRL" << "ALT" << "SHIFT";
    ui->cbDragon->addItems(commands);
    ui->cbBlueBuff->addItems(commands);
    ui->cbRedBuff->addItems(commands);
    ui->cbBaron->addItems(commands);
    ui->cbWard->addItems(commands);
    QString filename = QCoreApplication::applicationDirPath() +"/bindings.cfg";
    SaveManager::GetInstance()->LoadConfigs();

    load(filename, false);
}


MainWindow::~MainWindow()
{
    AudioOutputer::GetInstance()->Terminate();
    delete ui;
}

__declspec(dllexport) LRESULT CALLBACK HookProc (int nCode,WPARAM wParam,LPARAM lParam)
{
    if  ((nCode == HC_ACTION) && (wParam == WM_KEYDOWN || wParam == WM_SYSKEYDOWN))
    {
        int vk=0;
        int index=0;

        KBDLLHOOKSTRUCT hookstruct = *((KBDLLHOOKSTRUCT*)lParam);

        QStringList registeredBindings = SaveManager::GetInstance()->GetBindings();

        foreach(QString binding, registeredBindings){
            index++;
            if(binding.size() == 1) continue;

            if(binding.contains("SHIFT")){
                vk = VK_SHIFT;
            }else if(binding.contains("CTRL")){
                vk = VK_CONTROL;
            }
            else if(binding.contains("ALT")){
                vk = VK_MENU;
            } else {
                vk = 0;
            }

            if(vk!=0){
                if((GetAsyncKeyState(vk) & 0x8000) && binding.split(",").at(1) != NULL && binding.split(",").at(1).at(0).toAscii() == hookstruct.vkCode){
                    if(!SaveManager::GetInstance()->GetSkypeBot())
                        AudioOutputer::GetInstance()->OutputSound(index);
                    else
                        AudioOutputer::GetInstance()->OutputSoundMic(index);
                }
            }else if(binding.split(",").at(1) != NULL && binding.split(",").at(1).at(0).toAscii() == hookstruct.vkCode){
                if(!SaveManager::GetInstance()->GetSkypeBot())
                    AudioOutputer::GetInstance()->OutputSound(index);
                else
                    AudioOutputer::GetInstance()->OutputSoundMic(index);
            }
        }
    }
     return CallNextHookEx(hHook, nCode, wParam, lParam);

}

void MainWindow::on_txtDragon_textChanged(const QString &arg1)
{

}

void MainWindow::on_txtDragon_textEdited(const QString &arg1)
{
    ui->txtDragon->setText(arg1.toUpper());
    save();
}

void MainWindow::on_txtRedBuff_textEdited(const QString &arg1)
{
    ui->txtRedBuff->setText(arg1.toUpper());
    save();
}

void MainWindow::on_txtBlueBuff_textEdited(const QString &arg1)
{
    ui->txtBlueBuff->setText(arg1.toUpper());
    save();
}

void MainWindow::on_txtBaron_textEdited(const QString &arg1)
{
    ui->txtBaron->setText(arg1.toUpper());
    save();
}

void MainWindow::on_actionQuit_triggered()
{
    this->close();
}

void MainWindow::on_actionOpen_bindings_triggered()
{
    QDir *directory = new QDir("./");
    QString fileName = QFileDialog::getOpenFileName(this, tr("Import Bindings..."), directory->path().append("/bindings.cfg"),tr("*.cfg"));
    if(fileName.isEmpty()){
    return;
    }

    load(fileName,true);
}

void MainWindow::load(QString fileName, bool showError = true){

    QFile f(fileName);
    f.open(QIODevice::ReadOnly);
    QString content = f.readAll();
    f.close();

    QStringList list = content.split(",");

    int index = 0;

    if(list.length() != 10 && showError)
    {
        QString error = "The file you attempted to load was not formatted properly.\nSave a new binding file to have the proper format.";
        ErrorManager::GetInstance()->DisplayError(error);
        return;
    }

    bool empty = true;

    foreach(QString element, list){
        if(!element.isEmpty()){
            empty = false;
            break;
        }

    }

    if(empty) return;


    foreach(QString bindingElement, list)
    {
        switch(index)
        {

        case 0:
            ui->cbDragon->setCurrentIndex(ui->cbDragon->findText(bindingElement));
            ui->txtDragon->setText(list.at(index+1));
            break;
        case 2:
            ui->cbRedBuff->setCurrentIndex(ui->cbRedBuff->findText(bindingElement));
            ui->txtRedBuff->setText(list.at(index+1));
            break;
        case 4:
            ui->cbBlueBuff->setCurrentIndex(ui->cbBlueBuff->findText(bindingElement));
            ui->txtBlueBuff->setText(list.at(index+1));
            break;
        case 6:
            ui->cbBaron->setCurrentIndex(ui->cbBaron->findText(bindingElement));
            ui->txtBaron->setText(list.at(index+1));
            break;
        case 8:
            ui->cbWard->setCurrentIndex(ui->cbWard->findText(bindingElement));
            ui->txtWard->setText(list.at(index+1));
            break;

        }

        index++;
    }
    SaveManager::GetInstance()->ClearBindings();
    SaveManager::GetInstance()->AddBindings(ui->cbDragon->currentText().append(","+ui->txtDragon->text()));
    SaveManager::GetInstance()->AddBindings(ui->cbRedBuff->currentText().append(","+ui->txtRedBuff->text()));
    SaveManager::GetInstance()->AddBindings(ui->cbBlueBuff->currentText().append(","+ui->txtBlueBuff->text()));
    SaveManager::GetInstance()->AddBindings(ui->cbBaron->currentText().append(","+ui->txtBaron->text()));
    SaveManager::GetInstance()->AddBindings(ui->cbWard->currentText().append(","+ui->txtWard->text()));
}

void MainWindow::on_btnClear_clicked()
{

    ui->cbBaron->setCurrentIndex(0);
    ui->cbBlueBuff->setCurrentIndex(0);
    ui->cbRedBuff->setCurrentIndex(0);
    ui->cbDragon->setCurrentIndex(0);
    ui->cbWard->setCurrentIndex(0);

    ui->txtBaron->setText("");
    ui->txtBlueBuff->setText("");
    ui->txtRedBuff->setText("");
    ui->txtDragon->setText("");
    ui->txtWard->setText("");

    ui->lblMessage->setText("");

}
void MainWindow::on_btnConnect_clicked()
{
    if (!mystate) //If hook disabled then
    {

        SaveManager::GetInstance()->AddBindings(ui->cbDragon->currentText().append(","+ui->txtDragon->text()));
        SaveManager::GetInstance()->AddBindings(ui->cbRedBuff->currentText().append(","+ui->txtRedBuff->text()));
        SaveManager::GetInstance()->AddBindings(ui->cbBlueBuff->currentText().append(","+ui->txtBlueBuff->text()));
        SaveManager::GetInstance()->AddBindings(ui->cbBaron->currentText().append(","+ui->txtBaron->text()));
        SaveManager::GetInstance()->AddBindings(ui->cbWard->currentText().append(","+ui->txtWard->text()));

        if(!SaveManager::GetInstance()->BindingsOK()){
            SaveManager::GetInstance()->ClearBindings();
            QString error = "Please verify your bindings!\nThere might be duplicate or lonely system keys.";
            ErrorManager::GetInstance()->DisplayError(error);
            return;

        }

       save();

       // Activate hook
       hHook = SetWindowsHookEx( WH_KEYBOARD_LL, (HOOKPROC) HookProc, hExe, NULL);

       //Then put the state flag at 1 (hook active)
       mystate=1;

       ui->btnConnect->setText("Stop");
    }

       else // If hook already active
   {
    // Disable hook
    UnhookWindowsHookEx(hHook);
    AudioOutputer::GetInstance()->StopTimer();
    ui->btnConnect->setText("Start");

    // Put flagstate to 0 (disabled)
    mystate=0;

   }

}



void MainWindow::on_cbDragon_currentIndexChanged(int index)
{
    if(sem1==0){ sem1++; return;}
    save();
}

void MainWindow::on_cbRedBuff_currentIndexChanged(int index)
{
    if(sem2==0){ sem2++; return;}
    save();
}

void MainWindow::on_cbBlueBuff_currentIndexChanged(int index)
{
    if(sem3==0){ sem3++; return;}
    save();
}

void MainWindow::on_cbBaron_currentIndexChanged(int index)
{
    if(sem4==0){ sem4++; return;}
    save();
}

void MainWindow::save(){
    SaveManager::GetInstance()->AddBindings(ui->cbDragon->currentText().append(","+ui->txtDragon->text()));
    SaveManager::GetInstance()->AddBindings(ui->cbRedBuff->currentText().append(","+ui->txtRedBuff->text()));
    SaveManager::GetInstance()->AddBindings(ui->cbBlueBuff->currentText().append(","+ui->txtBlueBuff->text()));
    SaveManager::GetInstance()->AddBindings(ui->cbBaron->currentText().append(","+ui->txtBaron->text()));
    SaveManager::GetInstance()->AddBindings(ui->cbWard->currentText().append(","+ui->txtWard->text()));


     QString filename = QCoreApplication::applicationDirPath() +"/bindings.cfg";

    if(filename.isEmpty()){
        SaveManager::GetInstance()->ClearBindings();
        return;
    }
    SaveManager::GetInstance()->SaveBindings(filename);

}

void MainWindow::on_actionSave_triggered()
{
    SaveManager::GetInstance()->AddBindings(ui->cbDragon->currentText().append(","+ui->txtDragon->text()));
    SaveManager::GetInstance()->AddBindings(ui->cbRedBuff->currentText().append(","+ui->txtRedBuff->text()));
    SaveManager::GetInstance()->AddBindings(ui->cbBlueBuff->currentText().append(","+ui->txtBlueBuff->text()));
    SaveManager::GetInstance()->AddBindings(ui->cbBaron->currentText().append(","+ui->txtBaron->text()));
    SaveManager::GetInstance()->AddBindings(ui->cbWard->currentText().append(","+ui->txtWard->text()));

    if(SaveManager::GetInstance()->BindingsOK()){

        QDir *directory = new QDir("./");
        QString fileName = QFileDialog::getSaveFileName(this, tr("Save Bindings..."), directory->path().append("/bindings.cfg"),tr("*.cfg"));

        if(fileName.isEmpty()){
            SaveManager::GetInstance()->ClearBindings();
            return;
        }

        SaveManager::GetInstance()->SaveBindings(fileName);
    }else
    {
        QString error = "Please verify your bindings!\nThere might be duplicate or lonely system keys.";
        ErrorManager::GetInstance()->DisplayError(error);
    }


}


void MainWindow::on_cbWard_currentIndexChanged(int index)
{
    if(sem5==0){ sem5++; return;}
    save();
}

void MainWindow::on_txtWard_textChanged(const QString &arg1)
{
    ui->txtWard->setText(arg1.toUpper());
    save();
}

void MainWindow::on_actionSetup_triggered()
{
    settingWindow->show();
}
